<template>
  <div class="login">
    <header class="header">
      <div class="cover">
        <div class="logo">
          <!-- <img :src="$config.publicURL + 'img/logo/logo.png'" /> -->
          <img :src="logoSrc" />
        </div>
        <div class="lang-setting">
          <Select
            v-model="langConfig.current"
            style="width: 95px"
            @on-change="changeLang"
          >
            <Option
              v-for="item in langConfig.options"
              :value="item.value"
              :key="item.value"
              >{{ item.label }}</Option
            >
          </Select>
        </div>
      </div>
    </header>
    <main class="main">
      <div class="back">
        <Carousel
          trigger="hover"
          autoplay
          v-model="sliderConfig.current"
          :autoplay-speed="sliderConfig.interval"
          loop
          arrow="never"
          dots="none"
        >
          <CarouselItem v-for="(item, idx) of sliderConfig.content" :key="idx">
            <div
              class="slide-image"
              :style="{
                'background-image': 'url(' + item.background + ')',
                width: sliderControl.width + 'px',
                height: sliderControl.height + 'px'
              }"
            ></div>
          </CarouselItem>
        </Carousel>
      </div>
      <div class="front">
        <div class="cover">
          <div class="left"></div>
          <div class="right">
            <div class="login-box">
              <div class="login-title">
                <span>{{ $srv.getI18nByPath('system.login.sign_in') }}</span>
              </div>
              <div>
                <Form
                  ref="refLoginForm"
                  :model="loginForm"
                  :rules="loginRules"
                  inline
                >
                  <FormItem prop="userNo">
                    <!-- placeholder="用户名" -->
                    <i-input
                      type="text"
                      v-model="loginForm.userNo"
                      autocomplete="off"
                      size="large"
                      clearable
                      :placeholder="$srv.getI18nByPath('login.account')"
                    >
                      <Icon type="ios-person-outline" slot="prepend"></Icon>
                    </i-input>
                  </FormItem>
                  <FormItem prop="password">
                    <!-- placeholder="请输入登陆密码" -->
                    <i-input
                      :type="flag ? 'text' : 'password'"
                      v-model="loginForm.password"
                      autocomplete="off"
                      @keyup.enter.native="handleSubmit"
                      size="large"
                      clearable
                      :placeholder="$srv.getI18nByPath('login.enterpassword')"
                    >
                      <Icon type="ios-lock-outline" slot="prepend"></Icon>
                      <Icon
                        :class="
                          flag ? 'ios-eye-outline' : 'ios-eye-off-outline'
                        "
                        :type="flag ? 'ios-eye-outline' : 'ios-eye-off-outline'"
                        slot="append"
                        @click="flag = !flag"
                      ></Icon>
                    </i-input>
                  </FormItem>
                  <FormItem prop="dbName" v-if="isShow">
                    <div class="db-select-container">
                      <div class="db-select-icon-container">
                        <Icon size="14" type="ios-browsers-outline" />
                      </div>

                      <Select
                        v-model="loginForm.dbName"
                        size="large"
                        clearable
                        filterable
                        :placeholder="$t('login.selectAccSet')"
                      >
                        <Option
                          v-for="item in dbList"
                          :value="item.value"
                          :key="item.value"
                          >{{ item.label }}
                        </Option>
                      </Select>
                    </div>
                  </FormItem>
                  <FormItem>
                    <Button size="large" type="primary" @click="handleSubmit">
                      {{ $srv.getI18nByPath('login.login') }}
                      <!-- 登陆 -->
                    </Button>
                  </FormItem>
                </Form>
              </div>
              <!-- 忘记密码 -->
              <!-- <div class="login-func">
                <span @click="linkClick" to="/forget">
                  {{ $srv.getI18nByPath('login.forgotpassword') }}
                </span>
              </div> -->
            </div>
          </div>
        </div>
      </div>
    </main>
    <footer class="footer">
      <div class="cover">
        <div class="links">
          <!-- @click="linkClick" -->
          <span v-for="(link, idx) of linkConfig" :key="idx" :to="link.link">{{
            $srv.getI18nByPath(link.label)
          }}</span>
        </div>
        <div class="cert">
          <p>
            {{ copyRight }}
          </p>
        </div>
      </div>
    </footer>
  </div>
</template>
<script lang="ts">
import { T_srv, Tsrv, ifs, ts, vue } from '@/services';
import { Form } from 'view-design';
import cf from './config';

interface I_dbListRow {
  value: string;
  label: string;
}
//
@T_srv.comp
export default class Login extends vue {
  [x: string]: any;

  $refs!: {
    refLoginForm: Form;
  };

  public loginForm = {
    userNo: '',
    password: '',
    dbName: ''
  };

  private dbList: Array<I_dbListRow> = [];

  private flag: boolean = false;

  public isShow: boolean = false;

  private isStandardVersion = false;

  public logoSrc = 'img/logo/logo.jpg';

  private created() {
    this.init().then(r => {
      if (r.isErr()) {
        this.$msg('Initialization failed');
        throw new Error('Initialization failed');
      }
    });
    const info = cf.getProjectInfo();
    this.logoSrc = info.logoSrc;
    if (process.env.NODE_ENV !== 'production') {
      this.loginForm.userNo = process.env.VUE_APP_DEBUG_LOGIN_USER_NAME;
      this.loginForm.password = process.env.VUE_APP_DEBUG_LOGIN_USER_PASSWORD;
    }

    this.isStandardVersion = process.env.VUE_APP_VERSION_TYPE === 'standard';
    this.isShow = process.env.VUE_APP_VERSION_TYPE === 'standard';
    if (!this.isStandardVersion) {
      this.loginForm.dbName = process.env.VUE_APP_SYS_DBNAME;
    }
  }

  private mounted() {
    // this.$nextTick(() => {});
    // this.$languageSetter.initLanguage().then((lang: string) => {
    //   this.langConfig.current = lang;
    //   if (!lang) {
    //     console.info('lang is null');
    //   } else {
    //     if (process.env.VUE_APP_VERSION_TYPE === 'standard') {
    //       this.getAccSet(lang);
    //     }
    //     this.getTime();
    //   }
    // });
  }

  private async init(): Promise<ifs.I_return> {
    const lang = await this.$languageSetter.initLanguage().catch(e => {
      console.error(e);
      return undefined;
    });
    this.langConfig.current = lang;
    if (!lang) {
      return new ts.T_return('lang is null');
    }
    if (process.env.VUE_APP_VERSION_TYPE === 'standard') {
      const ok = await this.getAccSet(lang);
      if (!ok) {
        return new ts.T_return('getAccSet:Error');
      }
    }
    const ok = await this.getTime();
    if (!ok) {
      return new ts.T_return('getTime:Error');
    }
    return new ts.T_return();
  }

  public userNoValidate = (rule: object, value: any, callback: any) => {
    if (value === '') {
      // callback(new Error("请输入登录名"));
      callback(new Error(Tsrv.getI18nByPath('login.entername') as string));
    } else {
      callback();
    }
  };

  public passwordValidate = (rule: object, value: any, callback: any) => {
    if (value === '') {
      // callback(new Error("请输入密码"));
      callback(new Error(Tsrv.getI18nByPath('login.enterpassword') as string));
    } else {
      callback();
    }
  };

  public loginRules = {
    userNo: [
      { required: true, validator: this.userNoValidate, trigger: 'blur' }
    ],
    password: [
      { required: true, validator: this.passwordValidate, trigger: 'blur' }
    ],
    dbName: [
      { required: true, validator: this.dbNameValidate, trigger: 'blur' }
    ]
  };

  private langConfig = {
    current: '',
    options: [
      {
        value: 'zh-CN',
        label: '简体中文'
      },
      {
        value: 'en-US',
        label: 'English'
      },
      {
        value: 'zh-TW',
        label: '繁体中文'
      }
    ]
  };

  private sliderConfig = {
    current: 0,
    interval: 5000,

    content: this.getImgs()
  };

  getImgs(): Array<object> {
    const L_arr: Array<{ background: string }> = [];
    for (let i = 0; i < 5; i++) {
      L_arr.push({
        background: `${process.env.BASE_URL}img/banners/g1-${i}.jpg` // 本地图片地址
      });
    }
    return L_arr;
  }

  private linkConfig = [
    {
      // label: "隐私声明",
      label: 'login.privacystatement',
      link: '/about'
    },
    {
      // label: "客户服务",
      label: 'login.customerservice',
      link: '/custsvc'
    },
    {
      // label: "关于我们",
      label: 'login.aboutus',
      link: '/about'
    }
  ];

  private sliderControl = {
    width: document.body.clientWidth,
    height: document.body.clientHeight - 160
  };

  get copyRight() {
    return ``;
  }

  public linkClick(e: any) {
    this.$router.go(e.target.attributes.to);
  }

  // 改变语言
  public changeLang(val: string) {
    const chan = this.langConfig.options;
    for (const i in chan) {
      if (chan[i].value === val) {
        this.langConfig.current = chan[i].value;
        this.$languageSetter.setLanguage(chan[i].value);
        break;
      }
    }
  }

  private validate(callback) {
    const L_form: any = this.$refs.refLoginForm;
    let valid = true;
    if (L_form.fields.length > 0) {
      for (const field of L_form.fields) {
        field.validate('', errors => {
          if (errors) {
            valid = false;
          }
        });
        if (!valid) {
          break;
        }
      }
    }
    if (typeof callback === 'function') {
      callback(valid);
    }
  }

  public handleSubmit() {
    this.validate(valid => {
      if (valid) {
        this.login();
      } else {
        this.$Message.error('Fail!');
      }
    });
  }

  public login() {
    this.$Loading.start();
    const req: ifs.I_loginReq = new ts.T_loginReq();
    req.setUserNo(this.loginForm.userNo).setDbName(this.loginForm.dbName);
    const enResp = Tsrv.utils.EnCode(this.loginForm.password);
    if (enResp.isErr()) {
      throw new Error(enResp.getErrMsg());
    }
    req.setUsePass(enResp.getReturnData('data'));
    const that = this;
    Tsrv.standardPostReq<ifs.I_loginRes, ifs.I_loginReq>(req).then(r => {
      const [res, err] = r;
      if (err !== undefined) {
        that.$msg(err);
      } else {
        if (res.success) {
          that.$store
            .dispatch('Login', {
              userID: res.data.userID,
              userNo: res.data.userNo,
              userName: res.data.userName,
              dbName: req.dbName,
              token: res.data.token
            })
            .then(() => {
              this.$router.push({ path: Tsrv.lexicon.routerPath.root.path });
            })
            .catch(() => {
              throw new Error(
                '[view/login/index.js]在获取系统信息时发生意外错误!'
              );
            });
        } else {
          that.$msg(res.msg);
        }
      }
    });
  }

  public closeLoding() {
    // 删除起动load节点
    const loading = document.querySelector('#loading-layer') as HTMLDivElement;
    if (loading != null) {
      loading.style.opacity = '0';
      setTimeout(() => {
        document.body.removeChild(loading);
      }, 300);
    }
  }

  private getAccSet(lang: string): Promise<boolean> {
    const url: string = Tsrv.lexicon.url.getAccSet;
    const that = this;
    return new Promise(resolv => {
      Tsrv.standardPostReq<ifs.I_queryRes<I_dbListRow>, any>({ lang }, url)
        .then(r => {
          const [res, err] = r;
          if (err) {
            that.$msg(err);
            resolv(false);
          }
          if (res.success) {
            that.dbList = res.data.rows;
            resolv(true);
          } else {
            that.$msg(res.msg);
            resolv(false);
          }
        })
        .catch(e => {
          console.error(e);
          resolv(false);
        });
    });
  }

  private async getTime(): Promise<boolean> {
    const url: string = Tsrv.lexicon.url.getTime;
    const before = Date.now(); // 请求前的时间
    const that = this;
    const [res, err] = await Tsrv.standardGetReq<ifs.I_setDataRes<string>, any>(
      {},
      url
    );
    if (err) {
      that.$msg(err);
      return false;
    }

    if (!res.success) {
      that.$msg(res.msg);
      return false;
    }
    const after = Date.now(); // 请求后的时间
    const serverTimeMs = new Date(res.data).getTime();
    const roundTripTime = after - before;
    // 推算服务器真实时间（考虑网络延迟的一半）
    const estimatedServerTime = serverTimeMs + roundTripTime / 2;
    // 计算本地时间和服务器时间的差值（单位：ms）
    const timeDiff = after - estimatedServerTime;
    // 5分钟
    if (timeDiff >= 300000) {
      this.$msg(
        this.$msg(Tsrv.getI18nByMsg('50000', (timeDiff / 1000).toString()))
      );
      return false;
    }
    return true;
  }
}
</script>

<style scoped lang="scss">
//框架
.login {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}
.header {
  height: 80px;
  background-color: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  .logo {
    height: 100%;
    width: 100px;
    float: left;
    text-align: center;
    line-height: 80px;
    font-size: 27px;
    font-weight: bold;
    color: var(--default-hover-font-color);
    img {
      width: 100%;
      height: 100%;
    }
  }
  .lang-setting {
    height: 100%;
    width: 100px;
    position: absolute;
    right: 0;
    top: 0;
    .ivu-select {
      margin: 24px 0;
    }
  }
}
.main {
  flex-grow: 1;
  background-color: #ccc;
  position: relative;
  .back {
    position: absolute;
    z-index: 1;
    height: 100%;
    width: 100%;
    .ivu-carousel ::v-deep .ivu-carousel-dots {
      width: auto;
      left: 25%;
      transform: translate(-25%);
      bottom: 20px;
    }
    .slide-image {
      width: 100%;
      height: 100%;
      background-size: cover;
    }
  }
  .front {
    position: absolute;
    z-index: 2;
    display: flex;
    flex-direction: row;
    height: 100%;
    width: 100%;
    pointer-events: none;
    .left {
      pointer-events: none;
      flex: 1;
    }
    .right {
      width: 320px;
      display: flex;
      .login-box {
        // height: 360px;
        width: 320px;
        padding: 20px 40px;
        margin: auto 0;
        background-color: #fff;
        border-radius: 4px;
        box-shadow: 0 0 3px rgba(0, 0, 0, 0.05);
        pointer-events: auto;
        display: flex;
        flex-direction: column;
        position: relative;
        .login-title {
          height: 60px;
          line-height: 80px;
          font-size: 20px;
          color: #555;
        }
        .login-func {
          height: 44px;
          span {
            color: #999;
            font-size: 13px;
            float: right;
            cursor: pointer;
            display: block;
            height: 24px;
            margin: 10px 0;
            line-height: 24px;
            transition: var(--default-animation-hover);
          }
          span:hover {
            color: var(--default-hover-font-color);
          }
        }
        .login-other {
          position: absolute;
          bottom: 0;
          left: 0;
          height: 80px;
          width: 100%;
          background-color: #eee;
          border-bottom-left-radius: 4px;
          border-bottom-right-radius: 4px;
          box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1) inset;
          display: flex;
          flex-direction: row;
          .login-other-cell {
            flex: 1;
          }
        }
      }
    }
  }
}

.footer {
  height: 80px;
  background-color: #fff;
  box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);
  .cover {
    flex-direction: column;
    .links {
      height: 50px;
      line-height: 50px;
      span {
        color: #666;
        margin-right: 30px;
        font-size: 15px;
        transition: var(--default-animation-hover);
        cursor: pointer;
      }
      span:hover {
        color: var(--default-hover-font-color);
      }
    }
  }
  .cert {
    height: 30px;
    p {
      font-size: 13px;
      color: #888;
    }
  }
}
.login-box ::v-deep .ivu-form-inline .ivu-form-item {
  margin-right: 0;
  width: 100%;
  margin-bottom: 30px;
}
.login-box ::v-deep .ivu-form-inline .ivu-form-item:last-child {
  // margin-bottom: 0;
  margin-bottom: 20px;
}
.login-box ::v-deep .ivu-btn {
  width: 100%;
}
.login-box ::v-deep input {
  font-size: 14px;
}
.login-box ::v-deep .ivu-icon {
  font-weight: bold;
  color: #515a6e;
}
.login-box ::v-deep .ivu-input-icon {
  color: #bbb;
  font-size: 14px;
  font-weight: normal;
}
.cover {
  width: 998px;
  height: 100%;
  margin: 0 auto;
  position: relative;
  display: flex;
}
.db-select-icon-container {
  font-size: 14px;
  line-height: 30px;
  padding: 4px 7px;
  font-size: inherit;
  font-weight: normal;
  color: #515a6e;
  text-align: center;
  background-color: #f8f8f9;
  border: 1px solid #eaebef;
  border-right: 0px;
  border-bottom-left-radius: var(--default-border-radius-base);
  border-top-left-radius: var(--default-border-radius-base);
}
.db-select-container {
  display: flex;
  flex-direction: row;
  ::v-deep .ivu-select-selection {
    border-bottom-left-radius: 0 !important;
    border-top-left-radius: 0 !important;
  }
}
@media screen and (min-width: 1024px) {
  .cover {
    width: 1200px;
  }
}
</style>
